/**
 * @author Jonathan Jung, Timothy Hong, Ronen Adam
 */
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Router
{
	RouterEngine routerEngine;
	
	public Router() throws UnknownHostException, InstantiationException, SocketException
	{
		routerEngine = new RouterEngine();
		
	}
	
	
	public void run() throws UnknownHostException, InstantiationException, SocketException
	{
		Scanner input = new Scanner(System.in);
        String line = null;
        String[] parts = null;
        while (input.hasNextLine())
        {
        	System.out.println("Scanner input entry");
        	
        	
            line = input.nextLine();
            parts = line.split(" ");
            if (parts[0].compareToIgnoreCase("port") == 0)
            {
                /*
                 > port add <port number> <virtual IP/bits> <mtu>
                 > port del <port number>
                 */
                if (parts[1].compareToIgnoreCase("add") == 0)
                {
                    short portNum = Short.parseShort(parts[2]);
                    String[] sub = parts[3].split("/");
                    String ip = sub[0];
                    int subnet = Integer.parseInt(sub[1]);
                    int mtu = Integer.parseInt(parts[4]);
                    
                    //add function
                    addPort(portNum, ip, subnet,mtu);
                }
                else if (parts[1].compareToIgnoreCase("del") == 0)
                {
                    short port = Short.parseShort(parts[2]);
                    deletePort(port);
                }
                else
                {
                }
            }
            else if (parts[0].compareToIgnoreCase("connect") == 0)
            {
                /*
                 > connect add <local real port> <remote Real IP:port>
                 > connect del <local real port>
                 */
                if (parts[1].compareToIgnoreCase("add") == 0)
                {
                    short locPort = Short.parseShort(parts[2]);
                    String[] sub = parts[3].split(":");
                    String remIP = sub[0];
                    short remPort = Short.parseShort(sub[1]);
                    
                    addConnect(locPort, remIP, remPort);
                }
                else if (parts[1].compareToIgnoreCase("del") == 0)
                {
                	 short locPort = Short.parseShort(parts[2]);
                	 
                	 deleteConenct(locPort);
                }
                else
                {
                }
            }
            else if (parts[0].compareToIgnoreCase("route") == 0)
            {
                /*
                 > route add <network ID/subnet bits> <virtual IP>
                 > route del <network ID/subnet bits> <virtual IP>
                 */
                if (parts[1].compareToIgnoreCase("add") == 0)
                {
                	String netIP, virtIP;
                	int subnet = 0;
                	if (parts[2].compareToIgnoreCase("default") == 0)
                	{
                		netIP = parts[2];
                		virtIP = parts[3];
                	}
                	else
                	{
                		String[] sub = parts[2].split("/");
                		netIP = sub[0];
                		subnet = Integer.parseInt(sub[1]);
                		virtIP = parts[3];
                	}
                    addRoute(netIP, subnet, virtIP);
                }
                else if (parts[1].compareToIgnoreCase("del") == 0)
                {
                	String netIP, virtIP;
                	int subnet = 0;
                	if (parts[2].compareToIgnoreCase("default") == 0)
                	{
                		netIP = parts[2];
                		virtIP = parts[3];
                	}
                	else
                	{
                		String[] sub = parts[2].split("/");
                		netIP = sub[0];
                		subnet = Integer.parseInt(sub[1]);
                		virtIP = parts[3];
                	}
                    deleteRoute(netIP, subnet, virtIP);
                }
                else
                {
                }
            }
            else if (parts[0].compareToIgnoreCase("send") == 0)
            {
                /*
                 > send <SRC Virtual IP> <DST Virtual IP> <ID> <N bytes>
                 */
                String srcIP = parts[1];
                String destIP = parts[2];
                short ID = Short.parseShort(parts[3]);
                int N = Integer.parseInt(parts[4]);
                
                send(srcIP, destIP, ID, N);
            }
            else
            {
            }
        }
        input.close();
	}
	
	private void addPort(short portNum, String virtualIP, int subnet, int mtu)
	{
		routerEngine.addToPortMap(portNum, virtualIP, subnet, mtu);
	}
	
	private void deletePort(short portNum)
	{
		routerEngine.delFromPortMap(portNum);
	}

	private void addConnect(short locPort, String realIP, short remPort) throws UnknownHostException
	{
		routerEngine.connPort(locPort, realIP, remPort);
	}
	
	private void deleteConenct(short portNum)
	{
		routerEngine.disconPort(portNum);
	}
	
	private void addRoute(String netIP, int subnet, String virIP)
	{
		routerEngine.addRoute(netIP, subnet, virIP);
	}
	
	private void deleteRoute(String netIP, int subnet, String virIP)
	{
		routerEngine.delRoute(netIP, subnet, virIP);
	}
	
	private void send(String srcIP, String desIP, short ID, int N) throws InstantiationException, SocketException
	{
		routerEngine.send(srcIP, desIP, ID, N);
	}
	
    public static void main(String[] args)
    {
    	try {
			Router R = new Router();
			R.run();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}